﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace NetWork
{
    /// <summary>
    /// 包含了主动异步接收的方法实现和文件类异步读写的实现
    /// </summary>
    public class NetworkXBase : NetworkBase
    {
        #region Constractor
        /// <summary>
        /// 默认的无参构造方法
        /// </summary>
        public NetworkXBase()
        {
        }
        #endregion
        #region Protect Member
        #endregion
        #region Send Bytes Async
        /// <summary>
        /// 发送数据的方法
        /// </summary>
        /// <param name="session">通信用的核心对象</param>
        /// <param name="content">完整的字节信息</param>
        internal void SendBytesAsync(AppSession session, byte[] content)
        {
            if (content == null) return;
            try
            {
                // 进入发送数据的锁，然后开启异步的数据发送
                session.HybirdLockSend.Enter();
                // 启用另外一个网络封装对象进行发送数据
                AsyncStateSend state = new AsyncStateSend()
                {
                    WorkSocket = session.WorkSocket,
                    Data = content,
                    AlreadySendLength = 0,
                    HybirdLockSend = session.HybirdLockSend,
                };
                state.WorkSocket.BeginSend(
                    state.Data,
                    state.AlreadySendLength,
                    state.Data.Length - state.AlreadySendLength,
                    SocketFlags.None,
                    new AsyncCallback(SendCallBack),
                    state);
            }
            catch (ObjectDisposedException)
            {
                // 不操作
                session.HybirdLockSend.Leave();
            }
            catch (Exception ex)
            {
                session.HybirdLockSend.Leave();
                Logger.LogError(ToString(), ex);
            }
        }
        /// <summary>
        /// 发送回发方法
        /// </summary>
        /// <param name="ar"></param>
        internal void SendCallBack(IAsyncResult ar)
        {
            AsyncStateSend stateone = (AsyncStateSend)ar.AsyncState;
            if (stateone != null)
            {
                try
                {
                    stateone.AlreadySendLength += stateone.WorkSocket.EndSend(ar);
                    if (stateone.AlreadySendLength < stateone.Data.Length)
                    {
                        // 继续发送
                        stateone.WorkSocket.BeginSend(stateone.Data,
                        stateone.AlreadySendLength,
                        stateone.Data.Length - stateone.AlreadySendLength,
                        SocketFlags.None,
                        new AsyncCallback(SendCallBack),
                        stateone);
                    }
                    else
                    {
                        stateone.HybirdLockSend.Leave();
                        // 发送完成
                        stateone = null;
                    }
                }
                catch (ObjectDisposedException)
                {
                    stateone.HybirdLockSend.Leave();
                    // 不处理
                    stateone = null;
                }
                catch (Exception ex)
                {
                    Logger.LogError(ToString(), ex);
                    stateone.HybirdLockSend.Leave();
                    stateone = null;
                }
            }
        }
        #endregion
        #region Receive Bytes Async
        /// <summary>
        /// 重新开始接收下一次的数据传递
        /// </summary>
        /// <param name="session">网络状态</param>
        /// <param name="isProcess">是否触发数据处理</param>
        internal void ReBeginReceiveHead(AppSession session, bool isProcess)
        {
            try
            {
                byte[] head = session.BytesHead, Data = session.BytesContent;
                session.Clear();
                session.WorkSocket.BeginReceive(session.BytesHead, session.AlreadyReceivedHead, session.BytesHead.Length - session.AlreadyReceivedHead,
                    SocketFlags.None, new AsyncCallback(HeadBytesReceiveCallback), session);
                // 检测是否需要数据处理
                if (isProcess)
                {
                    // 校验令牌
                    if (CheckRemoteToken(head))
                    {
                        Data = HslProtocol.CommandAnalysis(head, Data);
                        int protocol = BitConverter.ToInt32(head, 0);
                        int customer = BitConverter.ToInt32(head, 4);
                        // 转移到数据中心处理
                        DataProcessingCenter(session, protocol, customer, Data);
                    }
                    else
                    {
                        // 应该关闭网络通信
                        Logger.LogWarn(ToString() + "接收验证令牌不一致");
                        AppSessionRemoteClose(session);
                    }
                }
            }
            catch (Exception ex)
            {
                SocketReceiveException(session, ex);
                Logger.LogError(ToString(), ex);
            }
        }
        /// <summary>
        /// 指令头接收方法
        /// </summary>
        /// <param name="ar">异步状态信息</param>
        protected void HeadBytesReceiveCallback(IAsyncResult ar)
        {
            AppSession session = (AppSession)ar.AsyncState;
            if (session != null)
            {
                try
                {
                    int receiveCount = session.WorkSocket.EndReceive(ar);
                    if (receiveCount == 0)
                    {
                        // 断开了连接，需要做个处理，一个是直接关闭，另一个是触发下线
                        AppSessionRemoteClose(session);
                        return;
                    }
                    else
                    {
                        session.AlreadyReceivedHead += receiveCount;
                    }
                }
                catch (ObjectDisposedException)
                {
                    // 不需要处理，来自服务器主动关闭
                    return;
                }
                catch (SocketException ex)
                {
                    // 已经断开连接了
                    SocketReceiveException(session, ex);
                    Logger.LogError(ToString(), ex);
                    return;
                }
                catch (Exception ex)
                {
                    // 其他乱七八糟的异常重新启用接收数据
                    ReBeginReceiveHead(session, false);
                    Logger.LogError(ToString(), ex);
                    return;
                }
                if (session.AlreadyReceivedHead < session.BytesHead.Length)
                {
                    try
                    {
                        // 仍需要接收
                        session.WorkSocket.BeginReceive(session.BytesHead, session.AlreadyReceivedHead,
                            session.BytesHead.Length - session.AlreadyReceivedHead,
                            SocketFlags.None, new AsyncCallback(HeadBytesReceiveCallback), session);
                    }
                    catch (Exception ex)
                    {
                        SocketReceiveException(session, ex);
                        Logger.LogError(ToString(), ex);
                    }
                }
                else
                {
                    // 接收完毕，校验令牌
                    if (!CheckRemoteToken(session.BytesHead))
                    {
                        Logger.LogWarn(ToString() + "接收验证令牌不一致");
                        AppSessionRemoteClose(session);
                        return;
                    }
                    int receive_length = BitConverter.ToInt32(session.BytesHead, session.BytesHead.Length - 4);
                    session.BytesContent = new byte[receive_length];
                    if (receive_length > 0)
                    {
                        try
                        {
                            int receiveSize = session.BytesContent.Length - session.AlreadyReceivedContent;
                            session.WorkSocket.BeginReceive(session.BytesContent, session.AlreadyReceivedContent, receiveSize,
                                SocketFlags.None, new AsyncCallback(ContentReceiveCallback), session);
                        }
                        catch (Exception ex)
                        {
                            SocketReceiveException(session, ex);
                            Logger.LogError(ToString(), ex);
                        }
                    }
                    else
                    {
                        // 处理数据并重新启动接收
                        ReBeginReceiveHead(session, true);
                    }
                }
            }
        }
        /// <summary>
        /// 数据内容接收方法
        /// </summary>
        /// <param name="ar"></param>
        private void ContentReceiveCallback(IAsyncResult ar)
        {
            AppSession receive = (AppSession)ar.AsyncState;
            if (receive != null)
            {
                try
                {
                    receive.AlreadyReceivedContent += receive.WorkSocket.EndReceive(ar);
                }
                catch (ObjectDisposedException)
                {
                    //不需要处理
                    return;
                }
                catch (SocketException ex)
                {
                    //已经断开连接了
                    SocketReceiveException(receive, ex);
                    Logger.LogError(ToString(), ex);
                    return;
                }
                catch (Exception ex)
                {
                    ReBeginReceiveHead(receive, false);
                    Logger.LogError(ToString(), ex);
                    return;
                }
                if (receive.AlreadyReceivedContent < receive.BytesContent.Length)
                {
                    int receiveSize = receive.BytesContent.Length - receive.AlreadyReceivedContent;
                    try
                    {
                        //仍需要接收
                        receive.WorkSocket.BeginReceive(receive.BytesContent, receive.AlreadyReceivedContent,
                            receiveSize, SocketFlags.None, new AsyncCallback(ContentReceiveCallback), receive);
                    }
                    catch (Exception ex)
                    {
                        ReBeginReceiveHead(receive, false);
                        Logger.LogError(ToString(), ex);
                    }
                }
                else
                {
                    //处理数据并重新启动接收
                    ReBeginReceiveHead(receive, true);
                }
            }
        }
        #endregion
        #region Token Check
        /// <summary>
        /// 检查当前的头子节信息的令牌是否是正确的
        /// </summary>
        /// <param name="headBytes">头子节数据</param>
        /// <returns>令牌是验证成功</returns>
        protected bool CheckRemoteToken(byte[] headBytes)
        {
            return Utils.IsByteTokenEquel(headBytes, Token);
        }
        #endregion
        #region Special Bytes Send
        /// <summary>
        /// [自校验] 发送字节数据并确认对方接收完成数据，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">网络套接字</param>
        /// <param name="headcode">头指令</param>
        /// <param name="customer">用户指令</param>
        /// <param name="send">发送的数据</param>
        /// <returns>是否发送成功</returns>
        protected Result SendBaseAndCheckReceive(Socket socket, int headcode, int customer, byte[] send)
        {
            // 数据处理
            send = HslProtocol.CommandBytes(headcode, customer, Token, send);
            // 发送数据
            Result sendResult = Send(socket, send);
            if (!sendResult.Success) return sendResult;
            // 检查对方接收完成
            Result<long> checkResult = ReceiveLong(socket);
            if (!checkResult.Success) return checkResult;
            // 检查长度接收
            if (checkResult.Data != send.Length)
            {
                socket.Close();
                return new Result("命令长度检查失败");
            }
            return checkResult;
        }
        /// <summary>
        /// [自校验] 发送字节数据并确认对方接收完成数据，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">网络套接字</param>
        /// <param name="customer">用户指令</param>
        /// <param name="send">发送的数据</param>
        /// <returns>是否发送成功</returns>
        protected Result SendBytesAndCheckReceive(Socket socket, int customer, byte[] send)
        {
            return SendBaseAndCheckReceive(socket, HslProtocol.ProtocolUserBytes, customer, send);
        }
        /// <summary>
        /// [自校验] 直接发送字符串数据并确认对方接收完成数据，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">网络套接字</param>
        /// <param name="customer">用户指令</param>
        /// <param name="send">发送的数据</param>
        /// <returns>是否发送成功</returns>
        protected Result SendStringAndCheckReceive(Socket socket, int customer, string send)
        {
            byte[] data = string.IsNullOrEmpty(send) ? null : Encoding.Unicode.GetBytes(send);
            return SendBaseAndCheckReceive(socket, HslProtocol.ProtocolUserString, customer, data);
        }
        /// <summary>
        /// [自校验] 将文件数据发送至套接字，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">网络套接字</param>
        /// <param name="filename">完整的文件路径</param>
        /// <param name="filelength">文件的长度</param>
        /// <param name="report">进度报告器</param>
        /// <returns>是否发送成功</returns>
        protected Result SendFileStreamToSocket(Socket socket, string filename, long filelength, Action<long, long> report = null)
        {
            try
            {
                Result result = null;
                using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    result = SendStream(socket, fs, filelength, report, true);
                }
                return result;
            }
            catch (Exception ex)
            {
                socket.Close();
                Logger.LogError(ToString(), ex);
                return new Result(ex.Message);
            }
        }
        /// <summary>
        /// [自校验] 将文件数据发送至套接字，具体发送细节将在继承类中实现，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <param name="filename">文件名称，文件必须存在</param>
        /// <param name="servername">远程端的文件名称</param>
        /// <param name="filetag">文件的额外标签</param>
        /// <param name="fileupload">文件的上传人</param>
        /// <param name="sendReport">发送进度报告</param>
        /// <returns>是否发送成功</returns>
        protected Result SendFileAndCheckReceive(
            Socket socket,
            string filename,
            string servername,
            string filetag,
            string fileupload,
            Action<long, long> sendReport = null
            )
        {
            // 发送文件名，大小，标签
            FileInfo info = new FileInfo(filename);
            if (!File.Exists(filename))
            {
                // 如果文件不存在
                Result stringResult = SendStringAndCheckReceive(socket, 0, "");
                if (!stringResult.Success) return stringResult;
                socket.Close();
                return new Result("文件不存在");
            }
            // 文件存在的情况
            Newtonsoft.Json.Linq.JObject json = new Newtonsoft.Json.Linq.JObject
            {
                { "FileName", new Newtonsoft.Json.Linq.JValue(servername) },
                { "FileSize", new Newtonsoft.Json.Linq.JValue(info.Length) },
                { "FileTag", new Newtonsoft.Json.Linq.JValue(filetag) },
                { "FileUpload", new Newtonsoft.Json.Linq.JValue(fileupload) }
            };
            // 先发送文件的信息到对方
            Result sendResult = SendStringAndCheckReceive(socket, 1, json.ToString());
            if (!sendResult.Success) return sendResult;
            // 最后发送
            return SendFileStreamToSocket(socket, filename, info.Length, sendReport);
        }
        /// <summary>
        /// [自校验] 将流数据发送至套接字，具体发送细节将在继承类中实现，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <param name="stream">文件名称，文件必须存在</param>
        /// <param name="servername">远程端的文件名称</param>
        /// <param name="filetag">文件的额外标签</param>
        /// <param name="fileupload">文件的上传人</param>
        /// <param name="sendReport">发送进度报告</param>
        /// <returns></returns>
        protected Result SendFileAndCheckReceive(
            Socket socket,
            Stream stream,
            string servername,
            string filetag,
            string fileupload,
            Action<long, long> sendReport = null
            )
        {
            // 文件存在的情况
            Newtonsoft.Json.Linq.JObject json = new Newtonsoft.Json.Linq.JObject
            {
                { "FileName", new Newtonsoft.Json.Linq.JValue(servername) },
                { "FileSize", new Newtonsoft.Json.Linq.JValue(stream.Length) },
                { "FileTag", new Newtonsoft.Json.Linq.JValue(filetag) },
                { "FileUpload", new Newtonsoft.Json.Linq.JValue(fileupload) }
            };
            // 发送文件信息
            Result fileResult = SendStringAndCheckReceive(socket, 1, json.ToString());
            if (!fileResult.Success) return fileResult;
            return SendStream(socket, stream, stream.Length, sendReport, true);
        }
        #endregion
        #region Special Bytes Receive
        /// <summary>
        /// [自校验] 接收一条完整的同步数据，包含头子节和内容字节，基础的数据，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <param name="timeout">超时时间设置，如果为负数，则不检查超时</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">result</exception>
        protected Result<byte[], byte[]> ReceiveAndCheckBytes(Socket socket, int timeout)
        {
            // 30秒超时接收验证
            HslTimeOut hslTimeOut = new HslTimeOut()
            {
                DelayTime = timeout,
                IsSuccessful = false,
                StartTime = DateTime.Now,
                WorkSocket = socket,
            };
            if (timeout > 0) ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), hslTimeOut);
            // 接收头指令
            Result<byte[]> headResult = Receive(socket, HslProtocol.HeadByteLength);
            if (!headResult.Success)
            {
                hslTimeOut.IsSuccessful = true;
                return Result.CreateFailedResult<byte[], byte[]>(headResult);
            }
            hslTimeOut.IsSuccessful = true;
            // 检查令牌
            if (!CheckRemoteToken(headResult.Data))
            {
                socket.Close();
                return new Result<byte[], byte[]>("接收验证令牌不一致");
            }
            int contentLength = BitConverter.ToInt32(headResult.Data, HslProtocol.HeadByteLength - 4);
            // 接收内容
            Result<byte[]> contentResult = Receive(socket, contentLength);
            if (!contentResult.Success) return Result.CreateFailedResult<byte[], byte[]>(contentResult);
            // 返回成功信息
            Result checkResult = SendLong(socket, HslProtocol.HeadByteLength + contentLength);
            if (!checkResult.Success) return Result.CreateFailedResult<byte[], byte[]>(checkResult);
            byte[] head = headResult.Data;
            byte[] content = contentResult.Data;
            content = HslProtocol.CommandAnalysis(head, content);
            return Result.CreateSuccessResult(head, content);
        }
        /// <summary>
        /// [自校验] 从网络中接收一个字符串数据，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <returns></returns>
        protected Result<int, string> ReceiveStringContentFromSocket(Socket socket)
        {
            Result<byte[], byte[]> receive = ReceiveAndCheckBytes(socket, 100000);
            if (!receive.Success) return Result.CreateFailedResult<int, string>(receive);
            // 检查是否是字符串信息
            if (BitConverter.ToInt32(receive.Data1, 0) != HslProtocol.ProtocolUserString)
            {
                Logger.LogWarn(ToString() + "命令头校验失败");
                socket.Close();
                return new Result<int, string>("命令头校验失败");
            }
            if (receive.Data2 == null) receive.Data2 = new byte[0];
            // 分析数据
            return Result.CreateSuccessResult(BitConverter.ToInt32(receive.Data1, 4), Encoding.Unicode.GetString(receive.Data2));
        }
        /// <summary>
        /// [自校验] 从网络中接收一串字节数据，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <returns></returns>
        protected Result<int, byte[]> ReceiveBytesContentFromSocket(Socket socket)
        {
            Result<byte[], byte[]> receive = ReceiveAndCheckBytes(socket, TimeOut);
            if (!receive.Success) return Result.CreateFailedResult<int, byte[]>(receive);
            // 检查是否是字节信息
            if (BitConverter.ToInt32(receive.Data1, 0) != HslProtocol.ProtocolUserBytes)
            {
                Logger.LogError(ToString() + "命令头校验失败");
                socket.Close();
                return new Result<int, byte[]>("命令头校验失败");
            }
            // 分析数据
            return Result.CreateSuccessResult(BitConverter.ToInt32(receive.Data1, 4), receive.Data2);
        }
        /// <summary>
        /// [自校验] 从套接字中接收文件头信息
        /// </summary>
        /// <param name="socket"></param>
        /// <returns></returns>
        protected Result<FileBaseInfo> ReceiveFileHeadFromSocket(Socket socket)
        {
            // 先接收文件头信息
            Result<int, string> receiveString = ReceiveStringContentFromSocket(socket);
            if (!receiveString.Success) return Result.CreateFailedResult<FileBaseInfo>(receiveString);
            // 判断文件是否存在
            if (receiveString.Data1 == 0)
            {
                socket.Close();
                return new Result<FileBaseInfo>("对方文件不存在，无法接收！");
            }
            Result<FileBaseInfo> result = new Result<FileBaseInfo>
            {
                Data = new FileBaseInfo()
            };
            try
            {
                // 提取信息
                Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(receiveString.Data2);
                result.Data.Name = Utils.GetValueFromJsonObject(json, "FileName", "");
                result.Data.Size = Utils.GetValueFromJsonObject(json, "FileSize", 0L);
                result.Data.Tag = Utils.GetValueFromJsonObject(json, "FileTag", "");
                result.Data.Upload = Utils.GetValueFromJsonObject(json, "FileUpload", "");
                result.Success = true;
            }
            catch (Exception ex)
            {
                socket.Close();
                result.Message = "Extra，" + ex.Message;
            }
            return result;
        }
        /// <summary>
        /// [自校验] 从网络中接收一个文件，如果结果异常，则结束通讯
        /// </summary>
        /// <param name="socket">网络套接字</param>
        /// <param name="savename">接收文件后保存的文件名</param>
        /// <param name="receiveReport">接收进度报告</param>
        /// <returns></returns>
        protected Result<FileBaseInfo> ReceiveFileFromSocket(Socket socket, string savename, Action<long, long> receiveReport)
        {
            // 先接收文件头信息
            Result<FileBaseInfo> fileResult = ReceiveFileHeadFromSocket(socket);
            if (!fileResult.Success) return fileResult;
            try
            {
                using (FileStream fs = new FileStream(savename, FileMode.Create, FileAccess.Write))
                {
                    WriteStream(socket, fs, fileResult.Data.Size, receiveReport, true);
                }
                return fileResult;
            }
            catch (Exception ex)
            {
                Logger.LogError(ToString(), ex);
                socket.Close();
                return new Result<FileBaseInfo>()
                {
                    Message = ex.Message
                };
            }
        }
        /// <summary>
        /// [自校验] 从网络中接收一个文件，写入数据流，如果结果异常，则结束通讯，参数顺序文件名，文件大小，文件标识，上传人
        /// </summary>
        /// <param name="socket">网络套接字</param>
        /// <param name="stream">等待写入的数据流</param>
        /// <param name="receiveReport">接收进度报告</param>
        /// <returns></returns>
        protected Result<FileBaseInfo> ReceiveFileFromSocket(Socket socket, Stream stream, Action<long, long> receiveReport)
        {
            // 先接收文件头信息
            Result<FileBaseInfo> fileResult = ReceiveFileHeadFromSocket(socket);
            if (!fileResult.Success) return fileResult;
            try
            {
                WriteStream(socket, stream, fileResult.Data.Size, receiveReport, true);
                return fileResult;
            }
            catch (Exception ex)
            {
                Logger.LogError(ToString(), ex);
                socket.Close();
                return new Result<FileBaseInfo>()
                {
                    Message = ex.Message
                };
            }
        }
        #endregion
        #region File Operate
        /// <summary>
        /// 删除文件的操作
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        protected bool DeleteFileByName(string filename)
        {
            try
            {
                if (!File.Exists(filename)) return true;
                File.Delete(filename);
                return true;
            }
            catch (Exception ex)
            {
                Logger.LogError(ToString(), ex);
                return false;
            }
        }
        /// <summary>
        /// 预处理文件夹的名称，除去文件夹名称最后一个'\'，如果有的话
        /// </summary>
        /// <param name="folder">文件夹名称</param>
        /// <returns></returns>
        protected string PreprocessFolderName(string folder)
        {
            if (folder.EndsWith(@"\"))
            {
                return folder.Substring(0, folder.Length - 1);
            }
            else
            {
                return folder;
            }
        }
        #endregion
        #region Virtual Method
        /// <summary>
        /// 数据处理中心，应该继承重写
        /// </summary>
        /// <param name="session">连接状态</param>
        /// <param name="protocol">协议头</param>
        /// <param name="customer">用户自定义</param>
        /// <param name="content">数据内容</param>
        internal virtual void DataProcessingCenter(AppSession session, int protocol, int customer, byte[] content)
        {
        }
        /// <summary>
        /// 接收出错的时候进行处理
        /// </summary>
        /// <param name="session">会话内容</param>
        /// <param name="ex">异常信息</param>
        internal virtual void SocketReceiveException(AppSession session, Exception ex)
        {
        }
        /// <summary>
        /// 当远端的客户端关闭连接时触发
        /// </summary>
        /// <param name="session"></param>
        internal virtual void AppSessionRemoteClose(AppSession session)
        {
        }
        #endregion
        #region Receive Long And Send Long
        /// <summary>
        /// 从网络中接收Long数据
        /// </summary>
        /// <param name="socket"></param>
        /// <returns></returns>
        private Result<long> ReceiveLong(Socket socket)
        {
            Result<byte[]> read = Receive(socket, 8);
            if (read.Success)
            {
                return Result.CreateSuccessResult(BitConverter.ToInt64(read.Data, 0));
            }
            else
            {
                return new Result<long>()
                {
                    Message = read.Message,
                };
            }
        }
        /// <summary>
        /// 将long数据发送到套接字
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private Result SendLong(Socket socket, long value)
        {
            return Send(socket, BitConverter.GetBytes(value));
        }
        #endregion
        #region StreamWriteRead
        /// <summary>
        /// 发送一个流的所有数据到网络套接字
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="stream"></param>
        /// <param name="receive"></param>
        /// <param name="report"></param>
        /// <param name="reportByPercent"></param>
        /// <returns></returns>
        protected Result SendStream(Socket socket, Stream stream, long receive, Action<long, long> report, bool reportByPercent)
        {
            byte[] buffer = new byte[102400]; // 100K的数据缓存池
            long SendTotal = 0;
            long percent = 0;
            stream.Position = 0;
            while (SendTotal < receive)
            {
                // 先从流中接收数据
                Result<int> read = ReadStream(stream, buffer);
                if (!read.Success) return new Result()
                {
                    Message = read.Message,
                };
                else
                {
                    SendTotal += read.Data;
                }
                // 然后再异步写到socket中
                byte[] newBuffer = new byte[read.Data];
                Array.Copy(buffer, 0, newBuffer, 0, newBuffer.Length);
                Result write = SendBytesAndCheckReceive(socket, read.Data, newBuffer);
                if (!write.Success)
                {
                    return new Result()
                    {
                        Message = write.Message,
                    };
                }
                // 报告进度
                if (reportByPercent)
                {
                    long percentCurrent = SendTotal * 100 / receive;
                    if (percent != percentCurrent)
                    {
                        percent = percentCurrent;
                        report.Invoke(SendTotal, receive);
                    }
                }
                else
                {
                    // 报告进度
                    report.Invoke(SendTotal, receive);
                }
            }
            return Result.CreateSuccessResult();
        }
        /// <summary>
        /// 从套接字中接收所有的数据然后写入到流当中去
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="stream"></param>
        /// <param name="totalLength"></param>
        /// <param name="report"></param>
        /// <param name="reportByPercent"></param>
        /// <returns></returns>
        protected Result WriteStream(Socket socket, Stream stream, long totalLength, Action<long, long> report, bool reportByPercent)
        {
            long count_receive = 0;
            long percent = 0;
            while (count_receive < totalLength)
            {
                // 先从流中异步接收数据
                Result<int, byte[]> read = ReceiveBytesContentFromSocket(socket);
                if (!read.Success)
                {
                    return new Result()
                    {
                        Message = read.Message,
                    };
                }
                count_receive += read.Data1;
                // 开始写入文件流
                Result write = WriteStream(stream, read.Data2);
                if (!write.Success)
                {
                    return new Result()
                    {
                        Message = write.Message,
                    };
                }
                // 报告进度
                if (reportByPercent)
                {
                    long percentCurrent = count_receive * 100 / totalLength;
                    if (percent != percentCurrent)
                    {
                        percent = percentCurrent;
                        if (report != null) report.Invoke(count_receive, totalLength);
                    }
                }
                else
                {
                    if (report != null) report.Invoke(count_receive, totalLength);
                }
            }
            return Result.CreateSuccessResult();
        }
        #endregion
        #region Object Override
        /// <summary>
        /// 获取本对象的字符串表示形式
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return "NetworkXBase";
        }
        #endregion
    }
    internal class AsyncStateSend
    {
        /// <summary>
        /// 传输数据的对象
        /// </summary>
        internal Socket WorkSocket { get; set; }
        /// <summary>
        /// 发送的数据内容
        /// </summary>
        internal byte[] Data { get; set; }
        /// <summary>
        /// 已经发送长度
        /// </summary>
        internal int AlreadySendLength { get; set; }
        internal SimpleHybirdLock HybirdLockSend { get; set; }
    }
    /// <summary>
    /// 文件的基础信息
    /// </summary>
    public class FileBaseInfo
    {
        /// <summary>
        /// 文件名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 文件大小
        /// </summary>
        public long Size { get; set; }
        /// <summary>
        /// 文件的标识，注释
        /// </summary>
        public string Tag { get; set; }
        /// <summary>
        /// 文件上传人的名称
        /// </summary>
        public string Upload { get; set; }
    }
}
